package com.nisco.dms.service;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.nisco.dms.entity.Department;
import com.nisco.dms.exception.ServiceException;
import com.nisco.dms.repository.DepartmentDao;
import com.nisco.dms.util.dwz.Page;
import com.nisco.dms.util.dwz.PageUtils;

/**
 * 
 * @author joey
 * 
 */
@Component
@Transactional(readOnly = true)
public class DepartmentService extends BaseService<Department, String> {

	private DepartmentDao departmentDao;

	public DepartmentService() {

	}

	@Autowired
	public DepartmentService(DepartmentDao departmentDao) {
		super((JpaRepository<Department, String>) departmentDao);
		this.departmentDao = departmentDao;
	}

	@Autowired
	public void setOrganizationDao(DepartmentDao departmentDao) {
		this.departmentDao = departmentDao;
	}

	@Transactional
	public void delete(String id) throws ServiceException {
		if (isRoot(id)) {
			throw new ServiceException("不允许删除根组织。");
		}

		Department department = this.get(id);

		// 先判断是否存在子模块，如果存在子模块，则不允许删除
		if (department.getChildren().size() > 0) {
			throw new ServiceException(department.getStrName() + "组织下存在子组织，不允许删除。");
		}

		departmentDao.delete(id);
	}

	public List<Department> find(String fatherId, Page page) {
		org.springframework.data.domain.Page<Department> p = departmentDao.findByFatherId(fatherId, PageUtils.createPageable(page));
		PageUtils.injectPageProperties(page, p);
		return p.getContent();
	}

	public List<Department> find(String parentId, String name, Page page) {
		org.springframework.data.domain.Page<Department> p = departmentDao.findByFatherIdAndStrNameContaining(parentId, name, PageUtils.createPageable(page));
		PageUtils.injectPageProperties(page, p);
		return p.getContent();
	}

	/**
	 * 判断是否是根组织.
	 */
	private boolean isRoot(String id) {
		return id == "1";
	}

	public Department getTree() {
		List<Department> list = departmentDao.findAllWithCache();

		List<Department> rootList = makeTree(list);

		return rootList.get(0);
	}

	private List<Department> makeTree(List<Department> list) {
		List<Department> parent = new ArrayList<Department>();
		// get parentId = null;
		for (Department e : list) {
			if (e.getParent() == null) {
				e.setChildren(new ArrayList<Department>(0));
				parent.add(e);
			}
		}
		// 删除parentId = null;
		list.removeAll(parent);

		makeChildren(parent, list);

		return parent;
	}

	private void makeChildren(List<Department> parent, List<Department> children) {
		if (children.isEmpty()) {
			return;
		}

		List<Department> tmp = new ArrayList<Department>();
		for (Department c1 : parent) {
			for (Department c2 : children) {
				c2.setChildren(new ArrayList<Department>(0));
				if (c1.getId().equals(c2.getParent().getId())) {
					c1.getChildren().add(c2);
					tmp.add(c2);
				}
			}
		}

		children.removeAll(tmp);

		makeChildren(tmp, children);
	}
}
